package com.beemans.common.utils

import android.app.Activity
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import com.beemans.common.ext.context
import com.beemans.common.utils.permissions.PermissionChecker
import com.beemans.common.utils.permissions.PermissionDialog
import com.blankj.utilcode.util.Utils
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.OnPermissionPageCallback
import com.hjq.permissions.XXPermissions
import com.tiamosu.fly.utils.deepClone

/**
 * @author tiamosu
 * @date 2021/3/19.
 */
class PermissionHelper {

    companion object {
        /** 权限设置页跳转请求码  */
        const val REQUEST_CODE = XXPermissions.REQUEST_CODE

        /**
         * 是否正在请求权限授权
         */
        var isPermissionRequesting = false

        fun with(owner: LifecycleOwner): Builder {
            return Builder(owner)
        }

        fun isGranted(vararg permission: String): Boolean {
            return XXPermissions.isGranted(Utils.getApp(), permission)
        }
    }

    class Builder(private val owner: LifecycleOwner) {
        private val permissionList by lazy { mutableListOf<String>() }
        private var onForwardToSettings: (() -> Boolean)? = null

        /**
         * 所有请求的权限，单个权限or权限组
         */
        fun permission(vararg permission: String): Builder {
            permissionList.addAll(permission)
            return this
        }

        /**
         * 针对那些被永久拒绝的权限向用户解释为什么它们是必须的，并自动跳转到应用设置当中提醒用户手动开启权限
         */
        fun onForwardToSettings(onForwardToSettings: () -> Boolean): Builder {
            this.onForwardToSettings = onForwardToSettings
            return this
        }

        fun request(
            onResult: (
                grantedList: List<String>,
                deniedList: List<String>,
                isGrantedAll: Boolean,
                isDeniedNever: Boolean
            ) -> Unit
        ) {
            isPermissionRequesting = true
            val grantedList = mutableListOf<String>()   //权限已授权集合
            val deniedList = mutableListOf<String>()    //权限被拒绝集合
            var isGrantedAll = false                    //是否所有权限都已授权
            var isDeniedNever = false                   //是否有权限禁止后不再询问
            var isResultWait = true

            val context = owner.context ?: return
            val newPermissionList = permissionList.deepClone() ?: permissionList
            PermissionChecker.optimizeDeprecatedPermission(newPermissionList)

            fun onPermissionResult(permissions: List<String>) {
                if (isResultWait && permissions.size != newPermissionList.size) {
                    isResultWait = false
                    return
                }
                val isForwardToSettings = onForwardToSettings?.invoke() ?: false
                val isToSetting = isForwardToSettings && isDeniedNever && deniedList.isNotEmpty()
                if (!isToSetting) {
                    isPermissionRequesting = false
                    onResult.invoke(grantedList, deniedList, isGrantedAll, isDeniedNever)
                    return
                }

                //展示权限被拒绝后弹框
                fun showSettingDialog(deniedList: List<String>, onGranted: () -> Unit) {
                    PermissionDialog.showPermissionDialog(context, deniedList, onPositiveAction = {
                        val onPermissionPageCallback = object : OnPermissionPageCallback {
                            override fun onGranted() {
                                onGranted.invoke()
                            }

                            override fun onDenied() {
                                val newDeniedList = XXPermissions.getDenied(context, deniedList)
                                showSettingDialog(newDeniedList, onGranted)
                            }
                        }
                        when (owner) {
                            is Activity -> XXPermissions.startPermissionActivity(
                                owner,
                                deniedList,
                                onPermissionPageCallback
                            )
                            is Fragment -> XXPermissions.startPermissionActivity(
                                owner,
                                deniedList,
                                onPermissionPageCallback
                            )
                        }
                    })
                }
                showSettingDialog(deniedList) {
                    isPermissionRequesting = false
                    onResult.invoke(newPermissionList, emptyList(), true, false)
                }
            }

            XXPermissions.with(context)
                .permission(permissionList)
                .request(object : OnPermissionCallback {
                    override fun onGranted(permissions: MutableList<String>, all: Boolean) {
                        isGrantedAll = all
                        grantedList.addAll(permissions)
                        onPermissionResult(permissions)
                    }

                    override fun onDenied(permissions: MutableList<String>, never: Boolean) {
                        isDeniedNever = never
                        deniedList.addAll(permissions)
                        onPermissionResult(permissions)
                    }
                })
        }
    }

    class PermissionCallback {
        internal var onResult: ((
            grantedList: List<String>,
            deniedList: List<String>,
            isGrantedAll: Boolean,
            isDeniedNever: Boolean
        ) -> Boolean)? = null

        internal var onDeniedAskPositive: ((
            deniedList: List<String>,
            isDeniedNever: Boolean
        ) -> Boolean)? = null

        internal var onDeniedAskNegative: ((
            deniedList: List<String>,
            isDeniedNever: Boolean
        ) -> Unit)? = null

        /**
         * 权限请求结果
         */
        fun onResult(
            onResult: (
                grantedList: List<String>,
                deniedList: List<String>,
                isGrantedAll: Boolean,
                isDeniedNever: Boolean
            ) -> Boolean
        ) {
            this.onResult = onResult
        }

        /**
         * 权限请求拒绝时，提示弹框积极回调
         */
        fun onDeniedAskPositive(
            onDeniedAskPositive: (
                deniedList: List<String>,
                isDeniedNever: Boolean
            ) -> Boolean
        ) {
            this.onDeniedAskPositive = onDeniedAskPositive
        }

        /**
         * 权限请求拒绝时，提示弹框消极回调
         */
        fun onDeniedAskNegative(
            onDeniedAskNegative: (
                deniedList: List<String>,
                isDeniedNever: Boolean
            ) -> Unit
        ) {
            this.onDeniedAskNegative = onDeniedAskNegative
        }
    }
}